<cfcomponent extends="assets.csac.com.Base">

	<cfscript>
        import assets.csac.com.service.ProductService;
		this.service = new ProductService();
	</cfscript>

	<cffunction name="get" output="false" access="remote" returntype="assets.csac.com.bo.Product">
		<cfreturn this.service.get(argumentCollection = arguments) />
	</cffunction>
	
	<cffunction name="query" output="false" access="public" returntype="query">
		<cfreturn this.service.read(argumentCollection = arguments) />
	</cffunction>
	
	<cffunction name="save" output="false" access="public" returntype="any">
        <cfscript>
			var product = "";
			var product_ = this.service.get(Product_ID = arguments.Product_ID);
			if (IsInstanceOf(arguments[1], "assets.csac.com.bo.Product")) {
				product = arguments[1];
			} else {
				var args = {};
				StructAppend(args, arguments);
				args.obj = Duplicate(product_);
				product = this.service.load(argumentCollection = args);
			}
			if (product.getDownload_Only() eq 1) {
				product.setInventory(0);
				product.setStock(0);
				product.setStock_Warn(0);
				product.setAllow_Back_Order(0);
				product.setPackage(0);
				product.setPackage_Quantity(0);
				product.setPackage_Only(0);
			} else {
				product.setDownload_Only(0);
				if (product.getInventory() eq 0) {
					product.setStock(0);
					product.setStock_Warn(0);
					product.setAllow_Back_Order(0);
				}
				if (product.getPackage() eq 0) {
					product.setPackage_Quantity(0);
					product.setPackage_Only(0);
				}
			}
			product.setProduct_ID(this.service.save(product));
			return product;
        </cfscript>
	</cffunction>
	
	<cffunction name="delete" output="false" access="public" returntype="boolean">
		<cfreturn this.service.destroy(argumentCollection = arguments) />
	</cffunction>
	
	<cffunction name="getImages" output="false" access="public" returntype="query">
		<cfargument name="Product_ID" type="numeric" required="yes" />
		<cfdirectory name="images" action="list" directory="#ExpandPath('/common/images/products/')#" filter="#arguments.Product_ID#.*" type="file" />
		<cfreturn images />
	</cffunction>
	
	<cffunction name="getFiles" output="false" access="public" returntype="query">
		<cfargument name="Product_ID" type="numeric" required="yes" />
		<cfdirectory name="files" action="list" directory="#ExpandPath('/common/files/products/')#" filter="#arguments.Product_ID#.*" type="file"  />
		<cfreturn files />
	</cffunction>
	
	<cffunction name="checkStock" output="false" access="public" returntype="any">
		<cfargument name="Product_ID" type="numeric" required="no" default="0" />
		<cfargument name="productIDs" type="string" required="no" default="" />
		<cfscript>
			var ret = StructNew();
			var products = "";
			var stock = {};
			var i = "";
			// init object structure
			stock.Rule = "";
			stock.Minimum = "";
			stock.Maximum = "";
			stock.Increment = "";
			if (arguments.Product_ID gt 0) {
				products = this.service.read(Product_ID = arguments.Product_ID);
			} else if (Len(Trim(arguments.productIDs)) gt 0) {
				products = this.service.read(productIDs = arguments.productIDs);
			} else {
				products = this.service.read(Active = 1);	
			}
			for (i=1; i<=products.RecordCount; i++) {
				stock = StructNew();
				stock.Product_ID = products.Product_ID[i];
				stock.Product = products.Product[i];
				stock.Category = products.Category[i];
				stock.Subcategory = products.Subcategory[i];
				stock.Download_Only = products.Download_Only[i];
				stock.Inventory = products.Inventory[i];
				stock.Stock = products.Stock[i];
				stock.Stock_Warn = products.Stock_Warn[i];
				stock.Allow_Back_Order = products.Allow_Back_Order[i];
				stock.Package = products.Package[i];
				stock.Package_Only = products.Package_Only[i];
				stock.Package_Quantity = products.Package_Quantity[i];
				// custom rule - soon to be Product min/max
				stock.Rule = "Custom";
				stock.Minimum = "";
				stock.Maximum = 2000;
				stock.Increment = "";
				// determine any inventory/stock related limitations
				if (stock.Inventory eq 1 AND stock.Allow_Back_Order eq 0) {
					stock.Rule = ListAppend(stock.Rule, "Inventory");
					if (stock.Stock lt stock.Maximum) {
						stock.Maximum = stock.Stock;
					}
				}
				// determine any package/increment related limitations
				if (stock.Package eq 1 AND stock.Package_Only eq 1) {
					stock.Rule = ListAppend(stock.Rule, "Package");
					stock.Maximum = Int(stock.Maximum/stock.Package_Quantity) * stock.Package_Quantity;
					stock.Increment = stock.Package_Quantity;
				}
				ret[stock.Product_ID] = stock;
			}
			return ret;
		</cfscript>
	</cffunction>
	
	<cffunction name="getQuantityLimits" output="false" access="public" returntype="any">
		<cfargument name="Product_ID" type="numeric" required="no" default="0" />
		<cfargument name="productIDs" type="string" required="no" default="" />
		<!---
			To Do
			If both Product_ID and productIDs are provided, append Product_ID to productIDs and return struct of structs.  Don't append Product_ID if it is already in productIDs
			Always return struct of structs with Product_ID key and struct value. Value struct has Minimum, Maximum and Increment keys
		--->
		<cfscript>
			var ret = StructNew();
			var products = "";
			var stock = {};
			var i = "";
			// init object structure
			stock.Rule = "";
			stock.Minimum = "";
			stock.Maximum = "";
			stock.Increment = "";
			if (arguments.Product_ID gt 0) {
				products = this.service.read(Product_ID = arguments.Product_ID);
			} else if (Len(Trim(arguments.productIDs)) gt 0) {
				products = this.service.read(productIDs = arguments.productIDs);
			} else {
				products = this.service.read(Active = 1);	
			}
			for (i=1; i<=products.RecordCount; i++) {
				stock = StructNew();
				stock.Product_ID = products.Product_ID[i];
				stock.Product = products.Product[i];
				stock.Category = products.Category[i];
				stock.Subcategory = products.Subcategory[i];
				stock.Download_Only = products.Download_Only[i];
				stock.Inventory = products.Inventory[i];
				stock.Stock = products.Stock[i];
				stock.Stock_Warn = products.Stock_Warn[i];
				stock.Allow_Back_Order = products.Allow_Back_Order[i];
				stock.Package = products.Package[i];
				stock.Package_Only = products.Package_Only[i];
				stock.Package_Quantity = products.Package_Quantity[i];
				// custom rule - soon to be Product min/max
				stock.Rule = "Custom";
				stock.Minimum = "";
				stock.Maximum = 2000;
				stock.Increment = "";
				// determine any inventory/stock related limitations
				if (stock.Inventory eq 1 AND stock.Allow_Back_Order eq 0) {
					stock.Rule = ListAppend(stock.Rule, "Inventory");
					if (stock.Stock lt stock.Maximum) {
						stock.Maximum = stock.Stock;
					}
				}
				// determine any package/increment related limitations
				if (stock.Package eq 1 AND stock.Package_Only eq 1) {
					stock.Rule = ListAppend(stock.Rule, "Package");
					stock.Maximum = Int(stock.Maximum/stock.Package_Quantity) * stock.Package_Quantity;
					stock.Increment = stock.Package_Quantity;
				}
				ret[stock.Product_ID] = stock;
			}
			return ret;
		</cfscript>
	</cffunction>
	
	<!--- <cffunction name="getStock" output="false" access="public" returntype="any">
		<cfargument name="Product_ID" type="numeric" required="no" default="0" />
		<cfargument name="productIDs" type="string" required="no" default="" />
		<cfscript>
			var ret = StructNew();
			var product = "";
			var products = "";
			var i = "";
			if (arguments.Product_ID gt 0) {
				products = this.service.read(Product_ID = arguments.Product_ID);
			} else if (Len(Trim(arguments.productIDs)) gt 0) {
				products = this.service.read(productIDs = arguments.productIDs);
			} else {
				products = this.service.read(Active = 1);	
			}
			for (i=1; i<=products.RecordCount; i++) {
				product = StructNew();
				product.Product_ID = products.Product_ID[i];
				product.Product = products.Product[i];
				product.Category = products.Category[i];
				product.Subcategory = products.Subcategory[i];
				product.Inventory = products.Inventory[i];
				product.Stock = products.Stock[i];
				product.Stock_Warn = products.Stock_Warn[i];
				product.Allow_Back_Order = products.Allow_Back_Order[i];
				product.Download_Only = products.Download_Only[i];
				product.Package_Only = products.Package_Only[i];
				product.Package = products.Package[i];
				product.Package_Quantity = products.Package_Quantity[i];
				// these are calculated properties
				product.Rule = "";
				product.Minimum = 0;
				product.Maximum = "";
				product.Increment = "";
				if (products.Download_Only[i] eq 0 AND products.Inventory[i] eq 1 AND products.Allow_Back_Order[i] eq 0) {
					product.Rule = "Inventory";
					product.Maximum = products.Stock[i];
				}
				if (products.Package[i] eq 1 AND products.Package_Only[i] eq 1) {
					if (product.Rule eq "Inventory,Package") {
						product.Maximum = Int(products.Stock[i]/products.Package_Quantity[i]) * products.Package_Quantity[i];
					} else {
						product.Rule = "Package";
					}
					product.Increment = products.Package_Quantity[i];
				}
				ret[product.Product_ID] = product;
			}
			return ret;
		</cfscript>
	</cffunction> --->

</cfcomponent>

<!--- stockLimit.Product_ID = products.Product_ID[i];
stockLimit.Product = products.Product[i];
stockLimit.Category = products.Category[i];
stockLimit.Subcategory = products.Subcategory[i];
stockLimit.Inventory = products.Inventory[i];
stockLimit.Stock = products.Stock[i];
stockLimit.Stock_Warn = products.Stock_Warn[i];
stockLimit.Allow_Back_Order = products.Allow_Back_Order[i];
stockLimit.Download_Only = products.Download_Only[i];
stockLimit.Package_Only = products.Package_Only[i];
stockLimit.Package = products.Package[i];
stockLimit.Package_Quantity = products.Package_Quantity[i]; --->